package gu.sql2java.excel.config;

import java.math.BigDecimal;
import java.util.Arrays;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;

import gu.sql2java.excel.annotations.ExcelColumn;
import gu.sql2java.excel.annotations.ExcelHandlerAdapter;
import gu.sql2java.excel.annotations.ExcelColumn.ColumnType;

import static net.gdface.utils.BeanPropertyUtils.isEmpty;

import static com.google.common.base.Preconditions.checkArgument;
import static gu.sql2java.excel.utils.MethodSupport.mergeAnnotaionFields;

/**
 * Excel输入输出配置对象
 * @author guyadong
 *
 */
public class ColumnConfig {
    /**
     * 导出时在excel中排序
     */
	private int sort = Integer.MAX_VALUE;
	/**
	 * 对象(Java Bean/Map/JSON)中的字段名.
	 */
	private String columnName = "";
	/**
	 * 导出到Excel中的名字.为空则与{@link #columnName}相等
	 */
    private  String name = "";
    /**
     * 默认整数(Integer,Long,Short)格式
     */
	private String integralFormat = "";
    /**
     * 日期格式, 如: yyyy-MM-dd
     */
    private  String dateFormat = "";

    /**
     * 读取内容转表达式 (如: 0=男,1=女,2=未知,*=错误值), '*'为匹配其他未定义值的表达式
     */
    private  String readConverterExp = "";

    /**
     * 分隔符，读取字符串组内容
     */
    private  String separator = ",";

    /**
     * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
     */
    private  int scale = -1;

    /**
     * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
     */
    private  int roundingMode = BigDecimal.ROUND_HALF_EVEN;

    /**
     * 导出时在excel中每个列的高度 单位为字符
     */
    private  double height = 14;

    /**
     * 导出时在excel中每个列的宽 单位为字符
     */
    private  double width = 16;

    /**
     * 文字后缀,如% 90 变成90%
     */
    private  String suffix = "";

    /**
     * 当值为空时,字段的默认值
     */
    private  String defaultValue = "";

    /**
     * 提示信息
     */
    private  String prompt = "";

    /**
     * 设置只能选择不能输入的列内容.
     */
    private  String[] combo = {};

    /**
     * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
     */
    private  boolean export = true;

    /**
     * 另一个类中的属性名称,支持多级获取,以小数点隔开
     */
    private  String targetAttr = "";

    /**
     * 是否自动统计数据,在最后追加一行统计数据总和
     */
    private  boolean statistics = false;

    /**
     * 导出类型（0数字 1字符串）
     */
    private  ColumnType cellType = ColumnType.STRING;

    /**
     * 导出字体颜色
     */
    private  IndexedColors color = null;
    /**
     * 单元格填充颜色
     */
    private IndexedColors fillColor = null;
    /**
     * 导出字段水平对齐方式
     */
    private  HorizontalAlignment horizontalAlign = null;

    /**
     * 自定义数据处理器
     */
    private  Class<?> handler = ExcelHandlerAdapter.class;

    /**
     * 自定义数据处理器参数
     */
    private  String[] args = {};
    /**
     * 指定字段读取方法名
     */
    private String readMethod = "";
    
    /**
     * 指定字段写入方法名
     */
    private String writeMethod= "";

	/**
	 * 默认构造方法
	 */
	public ColumnConfig() {
	}

	public ColumnConfig(String columnName) {
		checkArgument(!isEmpty(columnName),"columnName is empty or null");
		this.columnName = columnName;
	}
	public ColumnConfig(String columnName, String name) {
		checkArgument(!isEmpty(columnName),"columnName is empty or null");
		this.columnName = columnName;
		setName(name);
	}

	/**
	 * 构造方法<br>
	 * 从{@link ExcelColumn}注解构造对象
	 * @param annot
	 */
	public ColumnConfig(ExcelColumn annot) {
		if(null != annot){
			sort = annot.sort();
			columnName = annot.columnName();
			name = annot.name();
			integralFormat = annot.integralFormat();
			dateFormat = annot.dateFormat();
			readConverterExp = annot.readConverterExp();
			separator = annot.separator();
			scale = annot.scale();
			roundingMode = annot.roundingMode();
			height = annot.height();
			width = annot.width();
			suffix = annot.suffix();
			defaultValue = annot.defaultValue();
			prompt = annot.prompt();
			combo = annot.combo();
			export = annot.export();
			targetAttr = annot.targetAttr();
			statistics = annot.statistics();
			cellType = annot.cellType();
			setColor(annot.color());
			setFillColor(annot.fillColor());
			setHorizontalAlign(annot.horizontalAlign());
			handler = annot.handler();
			args = annot.args();
			readMethod = annot.readMethod();
			writeMethod = annot.writeMethod();
		}
	}
	/**
	 * 构造方法<br>
	 * 从{@link ExcelColumn}注解构造对象
	 * @param annot
	 * @param columnName
	 */
	public ColumnConfig(ExcelColumn annot, String columnName) {
		this(annot);
		setColumnName(columnName);
	}
	public int getSort() {
		return sort;
	}

	public ColumnConfig setSort(int sort) {
		this.sort = sort;
		return this;
	}

	public String getColumnName() {
		return columnName;
	}

	public ColumnConfig setColumnName(String columnName) {
		if(!isEmpty(columnName)) {
			this.columnName = columnName;
		}
		return this;
	}

	public String getName() {
		return name;
	}

	public ColumnConfig setName(String name) {
		if(!isEmpty(name)){
			this.name = name;
		}
		return this;
	}

	public String getIntegralFormat() {
		return integralFormat;
	}

	public ColumnConfig setIntegralFormat(String integralFormat) {
		if(!isEmpty(integralFormat)){
			this.integralFormat = integralFormat;
		}
		return this;
	}

	public String getDateFormat() {
		return dateFormat;
	}

	public ColumnConfig setDateFormat(String dateFormat) {
		if(!isEmpty(dateFormat)){
			this.dateFormat = dateFormat;
		}
		return this;
	}

	public String getReadConverterExp() {
		return readConverterExp;
	}

	public ColumnConfig setReadConverterExp(String readConverterExp) {
		if(!isEmpty(readConverterExp)){
			this.readConverterExp = readConverterExp;
		}
		return this;
	}

	public String getSeparator() {
		return separator;
	}

	public ColumnConfig setSeparator(String separator) {
		if(!isEmpty(separator)){
			this.separator = separator;
		}
		return this;
	}

	public int getScale() {
		return scale;
	}

	public ColumnConfig setScale(int scale) {
		this.scale = scale;
		return this;
	}

	public int getRoundingMode() {
		return roundingMode;
	}

	public ColumnConfig setRoundingMode(int roundingMode) {
		if(!isEmpty(roundingMode)){
			this.roundingMode = roundingMode;
		}
		return this;
	}

	public double getHeight() {
		return height;
	}

	public ColumnConfig setHeight(double height) {
		this.height = height;
		return this;
	}

	public double getWidth() {
		return width;
	}

	public ColumnConfig setWidth(double width) {
		this.width = width;
		return this;
	}

	public String getSuffix() {
		return suffix;
	}

	public ColumnConfig setSuffix(String suffix) {
		if(!isEmpty(suffix)){
			this.suffix = suffix;
		}
		return this;
	}

	public String getDefaultValue() {
		return defaultValue;
	}

	public ColumnConfig setDefaultValue(String defaultValue) {
		if(!isEmpty(defaultValue)){
			this.defaultValue = defaultValue;
		}
		return this;
	}

	public String getPrompt() {
		return prompt;
	}

	public void setPrompt(String prompt) {
		if(!isEmpty(prompt)){
			this.prompt = prompt;
		}
	}

	public String[] getCombo() {
		return combo;
	}

	public ColumnConfig setCombo(String[] combo) {
		if(!isEmpty(combo)){
			this.combo = combo;
		}
		return this;
	}

	public boolean isExport() {
		return export;
	}

	public ColumnConfig setExport(boolean export) {
		this.export = export;
		return this;
	}

	public String getTargetAttr() {
		return targetAttr;
	}

	public ColumnConfig setTargetAttr(String targetAttr) {
		if(!isEmpty(targetAttr)){
			this.targetAttr = targetAttr;
		}
		return this;
	}

	public boolean isStatistics() {
		return statistics;
	}

	public ColumnConfig setStatistics(boolean statistics) {
		this.statistics = statistics;
		return this;
	}

	public ColumnType getCellType() {
		return cellType;
	}

	public ColumnConfig setCellType(ColumnType cellType) {
		if(null!= cellType){
			this.cellType = cellType;
		}
		return this;
	}

	public IndexedColors getColor() {
		return color;
	}

	public ColumnConfig setColor(IndexedColors color) {
		if(null != color){
			this.color = color;
		}
		return this;
	}
	public ColumnConfig setColor(String color) {
		try{
			this.color = IndexedColors.valueOf(color);
		}catch (Exception e) {
			// DO NOTHING
		}
		return this;
	}

	public IndexedColors getFillColor() {
		return fillColor;
	}

	public ColumnConfig setFillColor(IndexedColors fillColor) {
		if(null != fillColor){
			this.fillColor = fillColor;
		}
		return this;
	}
	public ColumnConfig setFillColor(String fillColor) {
		try{
			this.fillColor = IndexedColors.valueOf(fillColor);
		}catch (Exception e) {
			// DO NOTHGIN
		}
		return this;
	}

	public HorizontalAlignment getHorizontalAlign() {
		return horizontalAlign;
	}

	public ColumnConfig setHorizontalAlign(HorizontalAlignment horizontalAlign) {
		if(null != horizontalAlign){
			this.horizontalAlign = horizontalAlign;
		}
		return this;
	}
	public ColumnConfig setHorizontalAlign(String horizontalAlign) {
		try{
			this.horizontalAlign = HorizontalAlignment.valueOf(horizontalAlign);
		}catch (Exception e) {
			// DO NOTHING
		}
		return this;
	}

	public Class<?> getHandler() {
		return handler;
	}

	public ColumnConfig setHandler(Class<?> handler) {
		if(null != handler){
			this.handler = handler;
		}
		return this;
	}

	public String[] getArgs() {
		return args;
	}

	public ColumnConfig setArgs(String[] args) {
		if(!isEmpty(args)){
			this.args = args;
		}
		return this;
	}

	public String getReadMethod() {
		return readMethod;
	}

	public ColumnConfig setReadMethod(String readMethod) {
		if(!isEmpty(readMethod)){
			this.readMethod = readMethod;
		}
		return this;
	}

	public String getWriteMethod() {
		return writeMethod;
	}

	public ColumnConfig setWriteMethod(String writeMethod) {
		if(!isEmpty(writeMethod)){
			this.writeMethod = writeMethod;
		}
		return this;
	}

	/**
	 * 将other中有定义的字段复制到当前对象<br>
	 * @param other
	 * @return 当前对象
	 * @see gu.sql2java.excel.utils.MethodSupport#mergeAnnotaionFields(Class, Object, Object)
	 */
	public ColumnConfig merge(ColumnConfig other){
		return mergeAnnotaionFields(ExcelColumn.class,other,this);
	}
	@Override
	public String toString() {
		return "ColumnConfig [sort=" + sort + ", columnName=" + columnName + ", name=" + name + ", integralFormat="
				+ integralFormat + ", dateFormat=" + dateFormat + ", readConverterExp=" + readConverterExp
				+ ", separator=" + separator + ", scale=" + scale + ", roundingMode=" + roundingMode + ", height="
				+ height + ", width=" + width + ", suffix=" + suffix + ", defaultValue=" + defaultValue + ", prompt="
				+ prompt + ", combo=" + Arrays.toString(combo) + ", export=" + export + ", targetAttr=" + targetAttr
				+ ", statistics=" + statistics + ", cellType=" + cellType + ", color=" + color + ", fillColor="
				+ fillColor + ", horizontalAlign=" + horizontalAlign + ", handler=" + handler + ", args=" + Arrays.toString(args)
				+ ", readMethod=" + readMethod + ", writeMethod=" + writeMethod + "]";
	}

}
